﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using MyValidationLibrary;
using System.Xml.Serialization;
using System.IO;
using SystemHelperLibrary;
using SystemHelperLibrary.Json;
using SystemHelperLibrary.FileExt;
using SystemHelperLibrary.RegistryWraper;
using RestEntities;
using System.Collections;
using SystemHelperLibrary.WcfClientExt;
using SystemHelperLibrary.Ini;

namespace ConsoleAppThread
{
	public enum Color
	{
		White = 0,
		Red,
		Green
	}

	[XmlRoot(ElementName = "XmlListData")]
	public class XmlListData
	{
		[XmlElement]
		public string Data1
		{
			get;
			set;
		}

		[XmlElement]
		public string Data2
		{
			get;
			set;
		}
	}

	[XmlRoot(ElementName = "TMP", Namespace = "www.MyTmp.com")]
	public class Tmp
	{
		public Tmp()
		{
			ListedData = new List<XmlListData>()
			{
				new XmlListData(){ Data1="1221", Data2="212121"},
				new XmlListData(){ Data1="1221", Data2="212121"}
			};
		}

		[XmlElement]
		public string Data
		{
			get;
			set;
		}

		[XmlAttribute]
		public int Value
		{
			get;
			set;
		}

		[XmlArray(ElementName = "ListedData")]
		public List<XmlListData> ListedData
		{
			get;
			set;
		}

	}

	class Program
	{
		private static WebServiceClient client = null;

		public static void InvokeCompleted(IAsyncResult result)
		{

			string returnFromService = client.EndInvokeService(result);
		}

		static EventWaitHandle eh = new AutoResetEvent(false);
		static EventWaitHandle ready = new AutoResetEvent(false);
		static EventWaitHandle go = new AutoResetEvent(false);
		static volatile string taskStr = null;

		static void Main(string[] args)
		{

			string response=SystemHelperLibrary.KeyboardExt.KeybordUtils.KeyboardSwitch("ghbdtn");
			Console.WriteLine(response);

			WcfLogger.WcfLogger.Instance.BackupLog("C:\\service.log", "D:\\servce.Backup.7z");
			
			List<WebServiceClient.WebServiceParameter> lstParameters = new List<WebServiceClient.WebServiceParameter>();

			var client = new WebServiceClient()
			{
				WebMethod = "GetCustomer",
				Url = "http://192.168.1.1:8080/CustomerService.svc",
				ServiceType = WebServiceClient.WebServiceType.WCF,
				WCFContractName = "ICustomerAgentWS",
				Parameters = lstParameters
			};
			client.BeginInvokeService(InvokeCompleted);



			Console.ReadLine();

			Dictionary<string, string> dict = new Dictionary<string, string>();

			for (int i = 0; i < 100; i++)
			{
				dict.Add(i + 1.ToString(), i + 1.ToString());
			}

			System.Xml.XmlWriterSettings set = new System.Xml.XmlWriterSettings();
			set.Indent = true;
			set.Encoding = Encoding.UTF8;

			using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create("c:\\1.xml", set))
			{
				writer.WriteStartDocument();
				writer.WriteStartElement("Datas");
				foreach (KeyValuePair<string, string> p in dict)
				{
					writer.WriteStartElement("Data");
					writer.WriteElementString("Key", p.Key);
					writer.WriteElementString("Value", p.Value);
					writer.WriteEndElement();
				}

				writer.WriteFullEndElement();

			}


			var icon = FileIconHelper.GetIcon("c:\\wcflog.txt", IconSize.Large);

			Console.WriteLine(FileAccessManager.ShareFolder("d:\\eBook", "MyShare", "Books container") == true ? "Created" : "Failed");

			using (FileStream fs = new FileStream("c:\\newIcon.ico", FileMode.Create))
			{
				icon.Save(fs);
			}

			icon = null;

			var dirAcc = FileAccessManager.GetDirectoryAccessRules("c:\\windows");

			using (StreamWriter sw = new StreamWriter("D:\\1.txt", false, Encoding.UTF8))
			{
				sw.WriteLine("sddsfdsfdssdf1");
				sw.WriteLine("sddsfdsfdssdf2");
				sw.WriteLine("sddsfdsfdssdf3");
				sw.WriteLine("sddsfdsfdssdf4");
			}

			Console.WriteLine(dirAcc);

			FileAccessManager.AddFullCntrolToFolder("c:\\windows");

			var text = FileAccessManager.GetFileAccessRules("D:\\1.txt");
			Console.WriteLine(text);

			FileAccessManager.AddFullCntrolToFile("D:\\1.txt");

			FileAccessManager.AddFullCntrolToFileForUser("D:\\1.txt", new System.Security.Principal.NTAccount(Environment.UserDomainName, Environment.UserName));

			Tmp tmp2 = new Tmp();
			Person person2 = SystemHelperLibrary.TypeHelper.ClassHelper.CtreateInstance<Person>();

			Person person3 = SystemHelperLibrary.TypeHelper.ClassHelper.CreateInstanceAndInitializeProperties<Person>();

			var p2 = person2;

			p2 = person3;

			string xmlSerData = SystemHelperLibrary.XmlExt.XmlSerializer<Tmp>.Xml.Serialize(tmp2);

			Console.WriteLine(xmlSerData);

			SystemHelperLibrary.FileExt.FileDeleter.DeleteFolder("D:\\ProgramData");

			SystemHelperLibrary.FileExt.UnfafeFileDeleter.DeleteFolder(new DirectoryInfo("D:\\Program Files"));

			string[] dataAssociation = FileAssociationInfo.GetExtensions();

			dataAssociation.ToList().ForEach(s => Console.WriteLine(s));

			Person person = new Person() { Comments = new List<Comment>(), LastName = "name", Name = "name", Id = Guid.NewGuid() };

			string json = person.Serialize<Person>();

			Console.WriteLine(json);

			Person newPerson = JsonHelper.Deserialize<Person>(json);
			Console.WriteLine(newPerson.LastName);

			Console.WriteLine(SystemHelper.IsConnectionAvailable() == true ? "Yes" : "No");

			Console.WriteLine(FileHelper.ComputeFileHash("c:\\WcfLog.txt"));

			string key = FileEncryptionHelper.GenerateKey();

			TripleDesFileEncryption.Encrypt("c:\\wcflog.txt", "c:\\wcflog2.txt", "c:\\key.key");
			TripleDesFileEncryption.Decrypt("c:\\wcflog2.txt", "c:\\key.key");

			FileEncryptionHelper.EncryptFile(key, "c:\\wcf2.txt", "c:\\wcf2encr.txt");

			FileEncryptionHelper.DecryptFile("c:\\wcf2encr.txt", "c:\\wcf2encr!!.txt", key);

			Console.WriteLine("Md5");

			string comp1 = FileHelper.ComputeMD5FileHash("d:\\Wcf2.txt");
			string comp2 = FileHelper.ComputeMD5FileHash("c:\\Wcf2.txt");
			Console.WriteLine(comp1);
			Console.WriteLine(comp2);

			Console.WriteLine("Sha1");

			Console.WriteLine(FileHelper.ComputeSha1FileHash("c:\\Wcflog.txt"));
			Console.WriteLine(FileHelper.ComputeSha1FileHashLowered("c:\\Wcflog.txt"));

			string salt = MyValidationLibrary.Helper.HashHelper.CreateRandomSalt();
			Console.WriteLine(salt);

			string passHash = MyValidationLibrary.Helper.HashHelper.ComputeSaltedHash("vax804", salt);

			Console.WriteLine(passHash);

			XmlSerializer ser = new XmlSerializer(typeof(Tmp));

			Tmp newTmp = null;

			using (MemoryStream memStream = new MemoryStream())
			{
				ser.Serialize(memStream, new Tmp() { Data = "1221213", Value = 12 });

				byte[] cont = new byte[memStream.Length];
				memStream.Seek(0, SeekOrigin.Begin);
				memStream.Read(cont, 0, cont.Length);
				string xmlContent = Encoding.UTF8.GetString(cont);
				if (File.Exists("c:\\1.xml"))
					File.Delete("c:\\1.xml");

				using (dynamic sw = new StreamWriter("c:\\1.xml"))
				{
					sw.WriteLine(xmlContent);
					sw.Flush();
				}

				Console.WriteLine(xmlContent);
			}

			using (StreamReader sr = new StreamReader("c:\\1.xml"))
			{
				newTmp = (Tmp)ser.Deserialize(sr);
			}

			var newTmp2 = newTmp;

			BusinessExample business = new BusinessExample();
			business.Data = "1321432423";
			business.Data2 = "1232134";
			business.Age = 10;
			business.Email = "asdasda@.asdsa.dsaas";

			MyValidatorManager manager = new MyValidationLibrary.MyValidatorManager(business);
			manager.Validate();

			if (manager.Errors.Count > 0)
			{
				manager.Errors.ForEach((data) => Console.WriteLine(data));
			}

			var m = business;

			Console.ReadLine();

			if (Enum.IsDefined(typeof(Color), "Green"))
			{
				Console.WriteLine("Yes");
			}

			Color c;

			c = (Color)Enum.Parse(typeof(Color), "Green");

			Console.WriteLine(c.ToString());

			string pair = "Resolution=12345";

			int ind = pair.IndexOf('=');

			Console.WriteLine(pair.Substring(0, ind));

			Console.WriteLine(pair.Substring(ind + 1, (pair.Length - 1 - ind)));

			IniReader ini = new IniReader("C:\\Games\\data.ini");
			ini.Load();

			foreach (string s in ini.GetKeys())
			{
				Console.WriteLine(s);
			}

			Console.WriteLine("--------------------------");

			foreach (string s in ini.GetValuesForKey("Data3"))
			{
				Console.WriteLine(s);
			}

			Console.WriteLine("-------------------------- data 5");

			foreach (string s in ini.GetValuesForKey("Data5"))
			{
				Console.WriteLine(s);
			}

			var d = ini.Data;


			var d2 = ini.Data2;

			MyMultiMap<string, string> dataDict = null;
			using (dataDict = new MyMultiMap<string, string>())
			{
				dataDict.Add("222", "2233");
				dataDict.Add("222", "22333");
				dataDict.Add("222", "22334");

				var task1 = Task.Factory.StartNew(() =>
				{
					dataDict.Add("1", "2233");
					dataDict.Add("1", "22333");
					dataDict.Add("1", "22334");
					dataDict.Add("3", "33333");
				});

				var task2 = Task.Factory.StartNew(() =>
				{
					dataDict.Add("2", "2233");
					dataDict.Add("2", "22333");
					dataDict.Add("4", "44444");
					dataDict.Add("2", "22334");
				});

				Task.WaitAll(task1, task2);

				foreach (KeyValuePair<string, List<string>> item in dataDict)
				{
					Console.WriteLine(item.Key);
					foreach (string s in item.Value)
					{
						Console.WriteLine(s);
					}
					Console.WriteLine("--------------------------------------------");
				}

				dataDict.EditValue("222", "22334", "223333");

				foreach (string s in dataDict.GetData("222"))
				{
					Console.WriteLine(s);
				}
			}

			Console.WriteLine("------------------------------------");

			foreach (KeyValuePair<string, List<string>> item in dataDict)
			{
				Console.WriteLine(item.Key);
			}

			Thread.Sleep(2000);

			var mre = new ManualResetEventSlim();

			Task task = null;
			task = Task.Factory.StartNew(() =>
				{
					Console.WriteLine("Task started.....");
					Thread.Sleep(1500);
					Console.WriteLine("Task going to be close.....");

					task.ContinueWith((previousTask) =>
						{
							Console.WriteLine("Task completed....");
							mre.Set();
						});
				});

			Console.WriteLine("Ожидание завершение Task-a");

			mre.Wait();

			//new Thread(Waiter).Start();
			//Thread.Sleep(1000);
			//eh.Set();

			new Thread(Work).Start();
			for (int i = 1; i <= 5; i++)
			{
				ready.WaitOne();
				taskStr = "a".PadRight(i, 'h');
				go.Set();
			}

			ready.WaitOne();
			task = null;
			go.Set();



			using (ProducerConsumerQueue q = new ProducerConsumerQueue())
			{
				q.EnqueueTask("Привет!");

				for (int i = 0; i < 10; i++)
					q.EnqueueTask("Сообщение " + i);

				q.EnqueueTask("Пока!");
			}


			ConcurrentBag<string> bag = new ConcurrentBag<string>();

			var t2 = Task.Factory.StartNew(() =>
				{
					Console.WriteLine("Begin adding");
					for (int i = 0; i < 1000; i++)
						bag.Add((i + 1).ToString());

					Console.WriteLine("End adding");

				});

			t2.ContinueWith((previousTask) =>
				{
					Console.WriteLine("Begin Peek");
					string s;
					if (bag.TryPeek(out s))
					{
						Console.WriteLine(s);
					}
					Console.WriteLine("End Peek");
					eh.Set();
				});

			eh.WaitOne();

			go.Close();
			ready.Close();



			Console.WriteLine("end");
			Console.ReadLine();
		}

		static void Waiter()
		{
			Console.WriteLine("Waiting .....");
			eh.WaitOne();
			Console.WriteLine("Signal getted");
		}

		static void Work()
		{
			while (true)
			{
				ready.Set();
				go.WaitOne();
				if (taskStr == null)
					return;

				Console.WriteLine(taskStr);
			}
		}
	}
}
